package io.github.wanggit.antrpc.console.web.utils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.yaml.snakeyaml.Yaml;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Enumeration;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;

@Slf4j
public abstract class StringToConfigMapUtil {

    /**
     * prop 转 map
     *
     * @param content prop
     * @return map
     */
    public static Map<String, String> propStrToMap(String content) {
        Map<String, String> datas = new TreeMap<>();
        ByteArrayInputStream byteArrayInputStream = null;
        try {
            Properties properties = new Properties();
            byteArrayInputStream =
                    new ByteArrayInputStream(content.getBytes(Charset.forName("UTF-8")));
            properties.load(byteArrayInputStream);
            Enumeration<?> propertyNames = properties.propertyNames();
            while (propertyNames.hasMoreElements()) {
                String name = propertyNames.nextElement().toString();
                datas.put(
                        StringUtils.trimAllWhitespace(name),
                        StringUtils.trimAllWhitespace(properties.getProperty(name)));
            }
        } catch (Exception e) {
            if (log.isErrorEnabled()) {
                log.error("parse prop to map error.", e);
            }
        } finally {
            if (null != byteArrayInputStream) {
                try {
                    byteArrayInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return datas;
    }

    /**
     * 把yaml 转为map
     *
     * @param content yaml
     * @return map
     */
    public static Map<String, String> yamlStrToMap(String content) {
        Map<String, String> datas = new TreeMap<>();
        try {
            Yaml yaml = new Yaml();
            Iterable<Object> iterable = yaml.loadAll(content);
            for (Object obj : iterable) {
                Map<String, Object> tmp = (Map<String, Object>) obj;
                tmp.forEach(
                        (key, value) -> {
                            internalYamlToMap(datas, key, value);
                        });
            }
        } catch (Exception e) {
            if (log.isErrorEnabled()) {
                log.error("parse yaml to map error.", e);
            }
        }
        return datas;
    }

    private static void internalYamlToMap(Map<String, String> targets, String fullKey, Object obj) {
        if (obj instanceof Map) {
            Map<String, Object> tmp = (Map<String, Object>) obj;
            tmp.forEach(
                    (key, value) -> {
                        internalYamlToMap(targets, fullKey + "." + key, value);
                    });
        } else {
            targets.put(fullKey, null == obj ? null : obj.toString());
        }
    }
}
